<template>
  <el-dialog :title="$t('tool.modelManage.parametricModeling')" :visible.sync="dialogFormVisible"
    :close-on-click-modal="false" width="60%" v-loading="!ready">
    <div class="parametric-modeling-out-box">
      <div class="parametric-modeling-box">
        <el-tabs v-model="activeName" @tab-click="handleClick">
          <!-- 基础属性 -->
          <el-tab-pane :label="$t('tool.modelManage.basicAttribute')" name="basicAttributeJsonSchemaForm">
            <span slot="label"><i class="el-icon-date"></i>
              {{ $t("tool.modelManage.basicAttribute") }}</span>
            <div class="parametric-modeling-jsonschema-content">
              <VueForm v-if="ready" ref="basicAttributeJsonSchemaForm" :formProps="formProps" :formFooter="formFooter"
                :schema="basicAttributeJsonSchemaData" v-model="submitForm.basicAttributeJson">
              </VueForm>
            </div>
          </el-tab-pane>
          <!-- 额外属性 -->
          <el-tab-pane :label="$t('tool.modelManage.extraAttribute')" name="extraAttributeJsonSchemaForm">
            <span slot="label"><i class="el-icon-document-copy"></i>
              {{ $t("tool.modelManage.extraAttribute") }}</span>
            <div class="parametric-modeling-jsonschema-content">
              <VueForm v-if="ready" ref="extraAttributeJsonSchemaForm" @form-mounted="formMounted"
                :formProps="formProps" :formFooter="formFooter" :schema="extraAttributeJsonSchemaData"
                :ui-schema="extraAttributeUiSchema" v-model="submitForm.extraAttributeJson">
              </VueForm>
            </div>
          </el-tab-pane>
          <!-- 型号属性 -->
          <el-tab-pane :label="$t('tool.modelManage.typeAttribute')" name="modelAttributeJsonSchemaForm">
            <span slot="label"><i class="el-icon-monitor"></i>
              {{ $t("tool.modelManage.typeAttribute") }}</span>
            <div class="parametric-modeling-jsonschema-content">
              <VueForm v-if="ready" ref="modelAttributeJsonSchemaForm" @form-mounted="formMounted"
                :formProps="formProps" :formFooter="formFooter" :schema="modelAttributeJsonSchemaData"
                :ui-schema="modelAttributeUiSchema" v-model="submitForm.modelAttributeJson">
              </VueForm>
            </div>

          </el-tab-pane>
          <!-- 文件属性 -->
          <el-tab-pane :label="$t('tool.modelManage.fileAttribute')" :name="$t('tool.modelManage.fileAttribute')">
            <span slot="label"><i class="el-icon-folder"></i>
              {{ $t("tool.modelManage.fileAttribute") }}</span>
            <el-input v-model="submitForm.fileAttributeUrl" disabled></el-input>
            <div class="model-upload loc-center parametric-modeling-file-content">
              <el-popover placement="top" :title="$t('tool.others.placehoderUpload')" trigger="hover">
                <span slot="reference" role="img" class="appIcon" @click="uploadModelFile('fileAttributeUrl')">
                  <svg-icon class="jtyj-active-color" icon-class="add" width="50" height="50" />
                </span>
              </el-popover>
            </div>
          </el-tab-pane>
          <!-- 视图属性 -->
          <el-tab-pane :label="$t('tool.modelManage.viewAttribute')" :name="$t('tool.modelManage.viewAttribute')">
            <span slot="label">
              <i class="el-icon-picture-outline"> </i>
              {{ $t("tool.modelManage.viewAttribute") }}</span>
            <el-input v-model="submitForm.viewAttributeUrl" disabled></el-input>
            <div class="model-upload loc-center parametric-modeling-file-content">
              <el-popover placement="top" :title="$t('tool.others.placehoderUpload')" trigger="hover">
                <span slot="reference" role="img" class="appIcon" @click="uploadModelFile('viewAttributeUrl')">
                  <svg-icon class="jtyj-active-color" icon-class="add" width="50" height="50" />
                </span>
              </el-popover>
            </div>
          </el-tab-pane>
          <!-- 目特属性 -->
          <el-tab-pane :label="$t('tool.modelManage.targetAttribute')" name="specialAttributeJsonSchemaForm">
            <span slot="label">
              <i class="el-icon-view"> </i>
              {{ $t("tool.modelManage.targetAttribute") }}</span>
            <div class="parametric-modeling-jsonschema-content">
              <VueForm v-if="ready" ref="specialAttributeJsonSchemaForm" @form-mounted="formMounted"
                :formProps="formProps" :formFooter="formFooter" :schema="specialAttributeJsonSchemaData"
                :ui-schema="specialAttributeUiSchema" v-model="submitForm.specialAttributeJson"></VueForm>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>
    </div>
    <div slot="footer" class="dialog-footer">
      <el-button class="jtyj-btn-cancel" @click="cancel">{{
        $t("setup.buttonText.cancel")
      }}</el-button>
      <el-button class="jtyj-btn-primary" @click="sendForm">{{
        $t("setup.buttonText.save")
      }}</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { getToken } from "@/utils/auth";
import { mapState } from "vuex";
import JsonSchema from "@/views/myspace/model-manage-tool/components/gradient.vue";
import JsonSchemaForm from "@/views/myspace/model-manage-tool/components/jsonschema-form.vue";
import jsonSchemaToolHandle from "@/utils/jsonSchema-tool.js";
import VueForm from '@lljj/vue-json-schema-form';
import {
  addModeling,
  updateModeling,
  getModelDataTree
} from "@/api/myspace/model-manage-tool/model-manage";
import { ready } from "jquery";
export default {
  props: {
    modelId: {
      type: Number,
      default: 0
    },
    mainVersionId: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      ready: false,
      title: "",
      dialogFormVisible: false,
      activeName: "",
      submitForm: {
        basicAttributeJson: {}, //基础属性
        extraAttributeJson: {}, //额外属性
        modelAttributeJson: {}, //型号属性
        specialAttributeJson: {}, //目特属性
        fileAttributeUrl: "", //文件属性路径地址
        viewAttributeJson: "", //视图属性路径地址
        modelId: "",
        userId: "",
      },
      formFooter: {
        show: false, // 是否显示默认底部
        okBtn: '保存', // 确认按钮文字
        cancelBtn: '取消' // 取消按钮文字
      },
      formProps: {
        layoutColumn: 1, // 1 2 3 ，支持 1 2 3 列布局，如果使用inline表单这里配置无效
        inline: true, // 行内表单模式，建议：开启时labelPosition不要配置top, antd不要配置labelCol wrapperCol
        inlineFooter: false, // 如果想要保存按钮和表单元素一行显示，需要配置 true
        labelSuffix: '：', // label后缀
        labelPosition: 'left', // 表单域标签的位置
        isMiniDes: true, // 是否优先mini形式显示描述信息（label文字和描述信息同行显示）
        defaultSelectFirstOption: true, // 单选框必填，是否默认选中第一个
        popover: {}, // 透传给ui 组件库的popver组件，比如element ui Popover，antd a-popover
        size: "mini"
      },
      extraAttributeUiSchema: {},
      modelAttributeUiSchema: {},
      specialAttributeUiSchema: {},
      modelDataList: [],
      basicAttributeJsonSchemaData: {
        "type": "object",
        "properties": {
          "chineseName": {
            "type": "string",
            "description": "中文名称",
            "title": "中文名称"
          },
          "englishName": {
            "type": "string",
            "description": "英文名称",
            "title": "英文名称"
          },
          "coordinates": {
            "type": "object",
            "properties": {
              "x": {
                "type": "number",
                "description": "经度",
                "title": "经度",
                "default": 0
              },
              "y": {
                "type": "number",
                "description": "纬度",
                "title": "纬度",
                "default": 0
              },
              "z": {
                "type": "number",
                "description": "高度",
                "title": "高度",
                "default": 0
              }
            },
            "x-apifox-orders": [
              "x",
              "y",
              "z"
            ],
            "description": "位置(经纬高)",
            "required": [
              "x",
              "y",
              "z"
            ],
            "title": "位置"
          },
          "modelStepSize": {
            "type": "number",
            "description": "步长",
            "title": "步长",
            "default": 0
          },
          "currentHealth": {
            "type": "number",
            "description": "血量",
            "title": "血量",
            "default": 0
          }
        },
        "x-apifox-orders": [
          "chineseName",
          "englishName",
          "coordinates",
          "modelStepSize",
          "currentHealth"
        ],
        "required": [
          "chineseName",
          "englishName",
          "coordinates",
          "modelStepSize",
          "currentHealth"
        ]
      }, //基础属性JsonSchema
      extraAttributeJsonSchemaData: {}, //额外属性JsonSchema
      modelAttributeJsonSchemaData: {}, //型号属性JsonSchema
      specialAttributeJsonSchemaData: {}, //目特属性JsonSchema
      jsonSchema: null, // 全局jsonSchema
    };
  },
  components: {
    JsonSchema,
    JsonSchemaForm,
    VueForm
  },
  computed: {
    ...mapState({
      userId: (state) => state.user.id,
    }),
  },
  watch: {
    ready: {
      handler(ready) {
        if (ready) {
          this.$nextTick(() => {
            this.changeUI()
          })
        }
      },
      immediate: true,
      deep: true
    }
  },
  created() {
  },
  mounted() {
    // 文件上传成功的回调
    this.$EventBus.$on("fileSuccess", (response) => {
      if (response.code == 200) {
        if (this.uploadFlag == "fileAttributeUrl") {
          this.$set(
            this.submitForm,
            "fileAttributeUrl",
            response.data.filePath
          );
          this.uploadFlag = "";
        } else if (this.uploadFlag == "viewAttributeUrl") {
          this.$set(
            this.submitForm,
            "viewAttributeUrl",
            response.data.filePath
          );
          this.uploadFlag = "";
        }
      } else {
        this.uploadFlag = "";
        this.$message.error(
          this.$toolHandle.getI18nName(
            this.$zh.setup.responseText,
            this.$en.setup.responseText,
            this.$i18n.locale,
            "error"
          )
        );
      }
      this.$EventBus.$emit("close");
    });
    this.activeName = "basicAttributeJsonSchemaForm";
  },
  methods: {
    // 获取模型动态链接库版本的文件名
    getFileName(filePath) {
      return !filePath ? "" : filePath.split("/").pop();
    },
    // 初始化提交表单数据
    initSubmitForm(schema) {
      const form = {};
      if (schema.properties) {
        for (const key in schema.properties) {
          if (schema.properties[key].type === "object") {
            form[key] = this.initSubmitForm(schema.properties[key]);
          } else if (schema.properties[key].type === "array") {
            form[key] = [];
          } else if (schema.properties[key].type === "string") {
            form[key] = "";
          } else if (schema.properties[key].type === "number") {
            form[key] = 0;
          } else if (schema.properties[key].type === "boolean") {
            form[key] = false;
          } else {
            form[key] = null;
          }
        }
      }
      return form;
    },
    getModelDataTree() {
      this.ready = false;
      getModelDataTree({
        modelId: this.modelId,
        mainVersion: this.mainVersionId,
      }).then((response) => {
        if (response.code == 200) {
          if (Array.isArray(response.data)) {
            this.modelDataList = response.data[0].commonTreeList;
            // TODO 结构改版后去除后面的 .children[0].data.jsonSchemaData
            // 检查并解析 extraAttributeJsonSchemaData
            const extraAttributeNode = this.modelDataList[0].children[3].children[0];

            if (extraAttributeNode && extraAttributeNode.data && extraAttributeNode.data.jsonSchemaData) {
              this.extraAttributeJsonSchemaData = JSON.parse(extraAttributeNode.data.jsonSchemaData);
              // 如果存在引用数据，对引用数据进行解析
              this.extraAttributeJsonSchemaData = this.jsonSchemaTool.resolveRefs(this.extraAttributeJsonSchemaData, this.jsonSchema)
              // 如果存在临时数据，对临时数据进行删除
              this.extraAttributeJsonSchemaData = this.jsonSchemaTool.removeTmpProperties(this.extraAttributeJsonSchemaData)
              this.submitForm.extraAttributeJson = this.submitForm.extraAttributeJson ? this.serializeDictArrays(this.submitForm.extraAttributeJson, this.extraAttributeJsonSchemaData) : this.initSubmitForm(this.extraAttributeJsonSchemaData);
              // 解析模型属性数据，抽取出对应的字典数据，赋值到uiSchema中
              this.extraAttributeUiSchema = this.jsonSchemaTool.generateNestedDictUISchema(this.extraAttributeJsonSchemaData);

            } else {
              console.warn('extraAttributeJsonSchemaData not found or invalid');
              this.extraAttributeJsonSchemaData = {};
              this.submitForm.extraAttributeJson = {};
            }

            // 检查并解析 modelAttributeJsonSchemaData
            const modelAttributeNode = this.modelDataList[0].children[2].children[0];
            if (modelAttributeNode && modelAttributeNode.data && modelAttributeNode.data.jsonSchemaData) {
              this.modelAttributeJsonSchemaData = JSON.parse(modelAttributeNode.data.jsonSchemaData);
              // 如果存在引用数据，对引用数据进行解析
              this.modelAttributeJsonSchemaData = this.jsonSchemaTool.resolveRefs(this.modelAttributeJsonSchemaData, this.jsonSchema)
              // 如果存在临时数据，对临时数据进行删除
              this.modelAttributeJsonSchemaData = this.jsonSchemaTool.removeTmpProperties(this.modelAttributeJsonSchemaData)
              this.submitForm.modelAttributeJson = this.submitForm.modelAttributeJson ? this.serializeDictArrays(this.submitForm.modelAttributeJson, this.modelAttributeJsonSchemaData) : this.initSubmitForm(this.modelAttributeJsonSchemaData);
              // 解析模型属性数据，抽取出对应的字典数据，赋值到uiSchema中
              this.modelAttributeUiSchema = this.jsonSchemaTool.generateNestedDictUISchema(this.modelAttributeJsonSchemaData);

            } else {
              console.warn('modelAttributeJsonSchemaData not found or invalid');
              this.modelAttributeJsonSchemaData = {};
              this.submitForm.modelAttributeJson = {};
            }

            // 检查并解析 specialAttributeJsonSchemaData
            const specialAttributeNode = this.modelDataList[0].children[4].children[0];
            if (specialAttributeNode && specialAttributeNode.data && specialAttributeNode.data.jsonSchemaData) {
              this.specialAttributeJsonSchemaData = JSON.parse(specialAttributeNode.data.jsonSchemaData);
              // 如果存在引用数据，对引用数据进行解析
              this.specialAttributeJsonSchemaData = this.jsonSchemaTool.resolveRefs(this.specialAttributeJsonSchemaData, this.jsonSchema)
              // 如果存在临时数据，对临时数据进行删除
              this.specialAttributeJsonSchemaData = this.jsonSchemaTool.removeTmpProperties(this.specialAttributeJsonSchemaData)
              this.submitForm.specialAttributeJson = this.submitForm.specialAttributeJson ? this.serializeDictArrays(this.submitForm.specialAttributeJson, this.specialAttributeJsonSchemaData) : this.initSubmitForm(this.specialAttributeJsonSchemaData);
              // 解析模型属性数据，抽取出对应的字典数据，赋值到uiSchema中
              this.specialAttributeUiSchema = this.jsonSchemaTool.generateNestedDictUISchema(this.specialAttributeJsonSchemaData);

            } else {
              console.warn('specialAttributeJsonSchemaData not found or invalid');
              this.specialAttributeJsonSchemaData = {};
              this.submitForm.specialAttributeJson = {};
            }
            this.ready = true;
          }
        }
      });
    },
    handleClick() {
      this.changeUI();
    },

    formMounted(formRef, { formData }) {
      console.log('formRef', formRef);
      console.log('formData', formData);


    },

    changeUI() {
      const button = document.querySelector('.arrayOrderList_bottomAddBtn .bottomAddBtn');
      if (button) {
        button.className = 'el-button el-button--primary el-button--mini';
        button.innerHTML = '<i class="el-icon-plus"></i><span> 添加元素</span>';
      }
    },
    // 点击上传文件
    uploadModelFile(val) {
      this.uploadFlag = val;
      this.$EventBus.$emit("openUploader", {
        token: getToken(),
        prefixFlag: 1,
        userId: this.userId,
      });
    },
    init(row, mainVersionId) {
      this.jsonSchemaTool = new jsonSchemaToolHandle(this);
      this.modelDataList = JSON.parse(localStorage.getItem("modelDataList"));
      this.jsonSchema = JSON.parse(localStorage.getItem("modelDataList")).concat(
        JSON.parse(localStorage.getItem("globalTreeData"))
      );
      this.dialogFormVisible = true;
      this.submitForm.mainVersionId = mainVersionId;
      this.reset();
      if (!row) {
        this.title = "addParametricModeling";
      } else {
        this.title = "editParametricModeling";
        let rep = JSON.parse(JSON.stringify(row));
        rep.basicAttributeJson = {};
        rep.basicAttributeJson.chineseName = rep.chineseName;
        rep.basicAttributeJson.englishName = rep.englishName;
        rep.basicAttributeJson.coordinates = JSON.parse(rep.coordinates);
        rep.basicAttributeJson.modelStepSize = rep.modelStepSize;
        rep.basicAttributeJson.currentHealth = rep.currentHealth;
        rep.extraAttributeJson = rep.extraAttributeJson ? JSON.parse(rep.extraAttributeJson) : {};
        rep.modelAttributeJson = rep.modelAttributeJson ? JSON.parse(rep.modelAttributeJson) : {};
        rep.specialAttributeJson = rep.specialAttributeJson ? JSON.parse(rep.specialAttributeJson) : {};
        this.submitForm = rep
      }
      this.getModelDataTree();
    },
    handleUpload(e, type) {
      if (
        Object.values(this.uploadFlag).filter((item) => item == true).length > 0
      )
        return;
      this.uploadFlag[type] = true;
      this.$EventBus.$emit("openUploader", {
        token: getToken(),
        prefixFlag: 2,
        userId: this.userId,
      });
    },
    reset() {
      this.submitForm = {
        modelId: this.modelId, //型号
        basicAttributeJson: {}, //基础属性
        extraAttributeJson: {}, //额外属性
        modelAttributeJson: {}, //型号属性
        specialAttributeJson: {}, //目特属性
        mainVersionId: this.mainVersionId, //主版本ID
        fileAttributeUrl: "", //文件属性路径地址
        viewAttributeJson: "", //视图属性路径地址
        userId: "",
      };
    },
    cancel() {
      this.dialogFormVisible = false;
    },

    // 校验表单
    async validateForms(activeName) {

      const formConfigs = [
        { ref: 'basicAttributeJsonSchemaForm', msg: '基础属性' },
        { ref: 'extraAttributeJsonSchemaForm', msg: '额外属性' },
        { ref: 'modelAttributeJsonSchemaForm', msg: '型号属性' },
        { ref: 'specialAttributeJsonSchemaForm', msg: '目特属性' }
      ];
      // 将当前正在填写的面板排列在第一位
      formConfigs.unshift(formConfigs.splice(formConfigs.findIndex(item => item.ref === activeName), 1)[0]);
      for (const { ref, msg } of formConfigs) {
        try {
          await this.$refs[ref].$refs.genEditForm.validate();
        } catch {
          this.$message.error(`${msg}校验失败`);
          throw new Error("校验终止") // 关键：主动抛出错误
        }
      }
    },
    async sendForm() {
      try {
        await this.validateForms(this.activeName) // 执行所有校验
      } catch {
        // 错误信息已在validateForms中显示，此处可处理全局逻辑
        return;
      }
      let rep = JSON.parse(JSON.stringify(this.submitForm));
      rep.extraAttributeJson = JSON.stringify(rep.extraAttributeJson)
      rep.modelAttributeJson = JSON.stringify(rep.modelAttributeJson)
      rep.specialAttributeJson = JSON.stringify(rep.specialAttributeJson)
      rep.chineseName = rep.basicAttributeJson.chineseName.trim();
      rep.englishName = rep.basicAttributeJson.englishName.trim();
      rep.coordinates = JSON.stringify(rep.basicAttributeJson.coordinates);
      rep.modelStepSize = rep.basicAttributeJson.modelStepSize;
      rep.currentHealth = rep.basicAttributeJson.currentHealth;

      if (!this.submitForm.modelingId) {
        addModeling(rep).then((response) => {
          if (response.code == 200) {
            this.$message.success(
              this.$toolHandle.getI18nName(
                this.$zh.setup.responseText,
                this.$en.setup.responseText,
                this.$i18n.locale,
                "success"
              )
            );
            this.$emit("refresh");
            this.dialogFormVisible = false;
          }
        });
      } else {
        updateModeling(rep).then((response) => {
          if (response.code == 200) {
            this.$message.success(
              this.$toolHandle.getI18nName(
                this.$zh.setup.responseText,
                this.$en.setup.responseText,
                this.$i18n.locale,
                "success"
              )
            );
            this.$emit("refresh");
            this.dialogFormVisible = false;
          }
        });
      }
    },


    /**
     * 序列化字典下的数组字段
     * @param {object} data - 原始数据
     * @param {object} schema - 对应的schema定义
     * @returns {object} 处理后的数据
     */
    serializeDictArrays(data, schema) {
      if (!schema || !schema.properties) return data;

      const result = JSON.parse(JSON.stringify(data));

      // 遍历schema的所有属性
      Object.keys(schema.properties).forEach(key => {
        const fieldSchema = schema.properties[key];

        if (fieldSchema.type === 'object' && fieldSchema.hasOwnProperty('patternProperties')) {
          // 处理对象类型的字段（字典）
          if (result[key] && typeof result[key] === 'object') {
            result[key] = this.processDictField(result[key], fieldSchema);
          }
        }
        // 不处理非对象类型的字段（包括顶层的数组）
      });

      return result;
    },

    // 处理字典字段，只序列化字典下的数组
    processDictField(obj, schema) {
      const result = { ...obj };

      // 1. 处理patternProperties（动态键名的属性）
      if (schema.patternProperties) {
        Object.keys(obj).forEach(key => {
          // 检查key是否符合某个pattern
          const isPatternMatch = Object.keys(schema.patternProperties).some(pattern => {
            const regex = new RegExp(pattern);
            return regex.test(key);
          });

          if (isPatternMatch) {
            const valueSchema = Object.values(schema.patternProperties)[0];
            if (valueSchema.type === 'array') {
              // 序列化数组（因为它在字典下）
              result[key] = JSON.stringify(obj[key]);
            } else if (valueSchema.type === 'object') {
              // 递归处理嵌套字典
              result[key] = this.processDictField(obj[key], valueSchema);
            }
          }
        });
      }

      // 2. 处理固定properties
      if (schema.properties) {
        Object.keys(schema.properties).forEach(propKey => {
          const propSchema = schema.properties[propKey];
          if (obj[propKey] !== undefined) {
            if (propSchema.type === 'array') {
              // 序列化数组（因为它在字典下）
              result[propKey] = JSON.stringify(obj[propKey]);
            } else if (propSchema.type === 'object') {
              // 递归处理嵌套字典
              result[propKey] = this.processDictField(obj[propKey], propSchema);
            }
          }
        });
      }

      return result;
    }
  },
};
</script>

<style scoped>
.parametric-modeling-out-box {
  display: flex;
}

.parametric-modeling-box {
  width: 100%;
}

.parametric-modeling-title {
  height: 30px;
  font-size: var(--ui-font-size-lg);
}

.parametric-modeling-jsonschema-content {
  max-height: 58vh;
  overflow: auto;
}

.parametric-modeling-file-content {
  height: 40vh;
}
</style>